/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jogo;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Vector;
import util.Constantes;
import gui.Telas;

/**
 *
 * @author Pablo
 */
public class JogoCliente {

    // ATRIBUTOS PRA ATUALIZAR A INTERFACE /////////////////////////////////////
    private int jogadorDaVez; // Identificador de quem deve jogar

    private int[] pecasJogadores; // Numero de pecas que kda jogador possui

    private Vector nomeJogadores; // Nome de kda jogador

    private Vector pecasDireita; // Pecas que estao na mesa do lado direito

    private Vector pecasEsquerda; // Pecas que estao na mesa do lado esquerdo

    private Telas telas;
    private int[] pontuacao;
    private int partida;
    // ATRIBUTOS PRA FAZER AS JOGADAS //////////////////////////////////////////
    private int posicao;
    private Jogador usuario;
    private int cabecaDireita;
    private int cabecaEsquerda;
    private int rodada;
    private int status; // Estado atual do jogo (Constantes.STATUS)

    private int toques;

    public JogoCliente(Telas telas, String nomeUsuario) {
        this.status = Constantes.STATUS_PROCURANDO_JOGO;
        this.telas = telas;

        this.pecasDireita = new Vector();
        this.pecasEsquerda = new Vector();
        this.nomeJogadores = new Vector();
        this.pecasJogadores = new int[4];
        this.usuario = new Jogador(nomeUsuario);
        this.pontuacao = new int[2];
    }

    public int getStatus() {
        return this.status;
    }

    public int getRodada() {
        return this.rodada;
    }

    public int getPartida() {
        return this.partida;
    }

    public Jogador getJogador() {
        return this.usuario;
    }

    public Vector getPecasDireita() {
        return this.pecasDireita;
    }

    public Vector getPecasEsquerda() {
        return this.pecasEsquerda;
    }

    public Vector getNomeJogadores() {
        return this.nomeJogadores;
    }

    public int getJogadorVez() {
        return this.jogadorDaVez;
    }

    public int[] getPecasJogadores() {
        return this.pecasJogadores;
    }

    public int[] getPontuacao() {
        return this.pontuacao;
    }

    public void acabarJogo() {
        // Implementar
    }

    public void atualizarStatusIniciar(DataInputStream dados, int conectados) throws IOException {
        if (this.nomeJogadores.size() < conectados) {
            System.out.println("JogoCliente.run(): Pegando os nomes dos jogadores");
            for (int i = 0; i < this.nomeJogadores.size(); i++) {
                dados.readUTF();
            }
            for (int i = this.nomeJogadores.size(); i < conectados; i++) {
                String nome = dados.readUTF();
                this.nomeJogadores.addElement(nome);
            }
            this.atualizarTelaConectados();
            this.status = Constantes.STATUS_ESPERANDO_INICIAR;
        }
    }

    private void atualizarTelaConectados() {
        this.telas.atualizarTelaConectados(this.nomeJogadores);
    }

    public void atualizarStatusJogada(DataInputStream dados) throws IOException {
        this.partida = dados.readInt();
        dados.readInt();
        boolean acabouPacote = false;

        while (!acabouPacote) {
            int pacoteStatus = dados.readInt();

            switch (pacoteStatus) {
                case Constantes.STATUS_FIM:
                    acabouPacote = true;
                    break;

                case Constantes.STATUS_JOGADOR_INICIANDO:
                    if (this.rodada == dados.readInt()) {
                        this.rodada = this.rodada + 1;
                        for (int i = 0; i < 4; i++) {
                            this.pecasJogadores[i] = 6;
                        }
                        this.posicao = dados.readInt();

                        Vector pecas = new Vector(10);
                        for (int i = 0; i < 6; i++) {
                            Peca peca = new Peca(dados.readInt(), dados.readInt());
                            pecas.addElement(peca);
                        }
                        this.usuario.setPecas(pecas);
                        this.status = Constantes.STATUS_ESPERANDO_JOGADA;

                        this.mostrarTelaJogo();
                        this.atualizarTelaJogo();
                    }
                    break;

                case Constantes.STATUS_JOGADA:
                    if (this.rodada == dados.readInt()) {
                        this.rodada = this.rodada + 1;
                        boolean foiToque = dados.readBoolean();
                        if (foiToque) {

                            this.toques++;
                            this.jogadorDaVez = (this.jogadorDaVez+1)%4;
                            this.telas.atualizarTelaJogo();
                            if(this.toques == 4) {
                                this.jogoTrancado();
                            }

                        } else {
                            this.toques = 0;
                            this.pegarJogada(dados);
                        }
                        
                    } else {
                        acabouPacote = true;
                    }
                    break;

                default:
                    System.out.println("JogoCliente.atualizarStatusJogada(): entrou no deafult");
                    acabouPacote = true;
            }
        }
    }

    private void pegarJogada(DataInputStream dados) throws IOException {
        int quemJogou = dados.readInt();
        int ladoJogado = dados.readInt();
        int valor1 = dados.readInt();
        int valor2 = dados.readInt();
        Peca peca = new Peca(valor1, valor2);
        
        this.pecasJogadores[quemJogou]--;
        if (this.posicao == quemJogou) {
            this.usuario.jogarPeca(peca);
        }

        if (ladoJogado == Constantes.LADO_DIREITO) {
            this.pecasDireita.addElement(peca);
            if (valor1 == this.cabecaDireita) {
                this.cabecaDireita = valor2;
            } else {
                this.cabecaDireita = valor1;
            }
        } else if (ladoJogado == Constantes.LADO_ESQUERDO) {
            this.pecasEsquerda.addElement(peca);
            if (valor1 == this.cabecaEsquerda) {
                this.cabecaEsquerda = valor2;
            } else {
                this.cabecaEsquerda = valor1;
            }
        } else {
            // Se foi primeira jogada
            this.jogadorDaVez = quemJogou;
            this.cabecaDireita = peca.getValor1();
            this.cabecaEsquerda = peca.getValor2();
            this.pecasEsquerda.addElement(peca);
            this.pecasDireita.addElement(peca);
        }
        this.jogadorDaVez = (this.jogadorDaVez+1)%4;
        this.atualizarTelaJogo();

        System.out.println("entrou");
        if (this.pecasJogadores[quemJogou] == 0) {
            this.bateramJogo(quemJogou, peca);
        }
    }
    
    private void jogoTrancado() {
        // Setar as variaveis para reiniciar a partida
        this.status = Constantes.STATUS_ESPERANDO_INICIAR;
        this.pecasEsquerda.removeAllElements();
        this.pecasDireita.removeAllElements();        
    }

    
    private void bateramJogo(int quemBateu, Peca pecaJogada) {
        System.out.println("JogoCliente.bateramJogo();");

        if(this.nomeJogadores.size() >= quemBateu) {
            String nome = (String)this.nomeJogadores.elementAt(quemBateu);
            this.telas.mostrarAlerta("Batida!! Quem bateu foi: " + nome);
        } else {
            this.telas.mostrarAlerta("Batida!! Quem bateu foi: " + quemBateu);            
        }
        int pontos = pecaJogada.getPontosBatida(this.cabecaDireita, this.cabecaEsquerda);
        this.pontuacao[quemBateu % 2] += pontos;
        System.out.println("JogoCliente.verificarBateuJogo(): pontuacao =" + pontuacao[0] + "X" + pontuacao[1]);

        // Setar as variaveis para reiniciar a partida
        this.status = Constantes.STATUS_ESPERANDO_INICIAR;
        this.pecasEsquerda.removeAllElements();
        this.pecasDireita.removeAllElements();
    }

    public boolean podeJogarPeca(int index, int lado) {
        return true;
        /*
        if (this.status == Constantes.STATUS_ESPERANDO_JOGADA) {
            if (this.rodada == 1) {
                return true;
            }
            if (this.rodada > 1 && this.jogadorDaVez == this.posicao) {
                Peca peca = (Peca) this.usuario.getPecas().elementAt(index);
                int valorCabeca;
                if (lado == Constantes.LADO_DIREITO) {
                    valorCabeca = this.cabecaDireita;
                } else {
                    valorCabeca = this.cabecaEsquerda;
                }
                if (peca.encaixa(valorCabeca)) {
                    return true;
                } else {
                    this.telas.mostrarAlerta("Esta peça não pode ser jogada");
                    return false;
                }
            } else {
                this.telas.mostrarAlerta("Nao está na sua vez de jogar");
            }
        }
        return false;*/
    }

    public Vector getPecaJogada(int index, int lado) {
        Peca peca = (Peca) this.usuario.getPecas().elementAt(index);

        Vector dados = new Vector();
        dados.addElement(this.usuario.getNome());
        dados.addElement(new Integer(lado));
        dados.addElement(new Integer(peca.getValor1()));
        dados.addElement(new Integer(peca.getValor2()));
        return dados;
    }

    public void verificarSeTocou() {
        if (this.usuario.podeJogar(this.cabecaEsquerda, this.cabecaDireita) != null) {
            this.telas.mostrarAlerta("Existe uma peça valida para jogar");
        } else {
            this.telas.mostrarAlerta("Tocou");
        }
    }

    private void atualizarTelaJogo() {
        this.telas.atualizarTelaJogo();
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            //OK
        }
    }

    private void mostrarTelaJogo() {
        this.telas.mostrarTelaJogo();
    }
}
